﻿using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using Hn.Command;
using Hn.Database.Contrib;
using Hn.Database.DAL;
using Hn.Database.Data;
using Microsoft.Extensions.Logging;
using MSocketCore.Hub;
using SuperSocket.Command;

namespace MSocketCore.MSocket
{
    [MyCmdFilter]
    [Command(Key = "0C")]
    public class AFN0C : IAsyncCommand<MySession, MyPackage>
    {
        private readonly MessageClient _client;
        private readonly ILogger<AFN0C> _logger;
        private readonly IMapper _mapper;

        public AFN0C(MessageClient client, IMapper mapper, ILogger<AFN0C> logger)
        {
            _client = client;
            _mapper = mapper;
            _logger = logger;
        }

        public ValueTask ExecuteAsync(MySession session, MyPackage info)
        {
            _logger.LogInformation($"App Recevice:{info.Sn}[Request]\n{info.Message}");
            switch (info._Fn)
            {
                case 1:
                    Sub1(info);
                    break;
                case 2:
                    Sub2(info);
                    break;
                case 58:
                    Sub58(info);
                    break;
            }

            return new ValueTask();
        }

        public void Sub1(MyRequestInfo info)
        {
            var version = Encoding.ASCII.GetString(info.Content.Skip(12).Take(4).Reverse().ToArray());
            var dtu = DtuDAL.GetBySn(info.Sn);
            DtuExtendDAL.UpdatVersion(dtu.Id, dtu.Sn, version);
            var name = UserDAL.GetUserIdBySn(info.Sn);
            _client.SendInfo(name, info.Sn + "Version: " + version);
        }

        public void Sub2(MyRequestInfo info)
        {
            var time = CmdHelper.GetBCD_A1(info.Content.Take(6).ToArray());
            var name = UserDAL.GetUserIdBySn(info.Sn);
            _client.SendInfo(name, info.Sn + "Time: " + time);
        }

        private void Sub58(MyRequestInfo info)
        {
            var content = info.Content;
            var count = content[5];
            //var lampdata = new Data();

            //lampdata.Sn = info.Sn;
            //lampdata.Count = content[5];
            //lampdata.Updatetime = CmdHelper.GetBCD_A16(content.Take(5).ToArray());
            var dt = CmdHelper.GetBCD_A16(content.Take(5).ToArray());
            var datalen = 17;
            for (var i = 0; i < count; i++)
            {
                var model = new LampData();
                model.Sn = info.Sn;
                model.Index = i;
                model.Updatetime = dt;
                model.Pole = info.Sn;
                model.Activepower =
                    CmdHelper.GetBCD_A10(content.Skip(6 + i * datalen).Take(3).ToArray()) * 1000; //kw => w
                model.Reactivepower =
                    CmdHelper.GetBCD_A10(content.Skip(9 + i * datalen).Take(3).ToArray()) * 1000; //kw => w
                //model.Factor = CmdHelper.GetBCD_A6(content.Skip(12).Take(2 + i * datalen).ToArray());
                model.Factor = 0.98m;
                model.Voltage = CmdHelper.GetBCD_A8(content.Skip(14).Take(2 + i * datalen).ToArray()); //V
                model.Current = CmdHelper.GetBCD_A26(content.Skip(16).Take(3 + i * datalen).ToArray()) / 10; //A
                model.Power = CmdHelper.GetBCD_A10(content.Skip(19).Take(3 + i * datalen).ToArray());
                model.Light = SubLight(content[22], model.Sn, dt);
                LampDataDAL.Insert(model);

                var realtimedata = _mapper.Map<LampData, LampData_Realtime>(model);
                var data = LampData_RealtimeDAL.GetData(realtimedata.Sn, i);
                if (data == null)
                {
                    DbHelper.Conn().Insert(realtimedata);
                }
                else
                {
                    _mapper.Map(realtimedata, data);
                    DbHelper.Conn().Update(data);
                }

                //LampData_RealtimeDAL.UpdateRealtime(realtimedata, i, _mapper);


                //if (i == 0)
                //{
                //    lampdata.Activepower = CmdHelper.GetBCD_A10(content.Skip(6).Take(3).ToArray());
                //    lampdata.Reactivepower = CmdHelper.GetBCD_A10(content.Skip(9).Take(3).ToArray());
                //    lampdata.Factor = CmdHelper.GetBCD_A6(content.Skip(12).Take(2).ToArray());
                //    lampdata.Voltage = CmdHelper.GetBCD_A8(content.Skip(14).Take(2).ToArray());
                //    lampdata.Current = CmdHelper.GetBCD_A26(content.Skip(16).Take(3).ToArray());
                //    lampdata.Power = CmdHelper.GetBCD_A10(content.Skip(19).Take(3).ToArray());
                //    lampdata.Light = SubLight(content[22],lampdata.Sn, lampdata.Updatetime);

                //}
                //else if (i == 1)
                //{
                //    lampdata.Activepower2 = CmdHelper.GetBCD_A10(content.Skip(6 + i * datalen).Take(3).ToArray());
                //    lampdata.Reactivepower2 = CmdHelper.GetBCD_A10(content.Skip(9 + i * datalen).Take(3).ToArray());
                //    lampdata.Factor2 = CmdHelper.GetBCD_A6(content.Skip(12 + i * datalen).Take(2).ToArray());
                //    lampdata.Voltage2 = CmdHelper.GetBCD_A6(content.Skip(14 + i * datalen).Take(2).ToArray());
                //    lampdata.Current2 = CmdHelper.GetBCD_A26(content.Skip(16 + i * datalen).Take(3).ToArray());
                //    lampdata.Power2 = CmdHelper.GetBCD_A10(content.Skip(19 + i * datalen).Take(3).ToArray());
                //    lampdata.Light2 = SubLight(content[22 + i * datalen], lampdata.Sn, lampdata.Updatetime);
                //}
                //else if (i == 2)
                //{
                //    lampdata.Activepower3 = CmdHelper.GetBCD_A10(content.Skip(6 + i * datalen).Take(3).ToArray());
                //    lampdata.Reactivepower3 = CmdHelper.GetBCD_A10(content.Skip(9 + i * datalen).Take(3).ToArray());
                //    lampdata.Factor3 = CmdHelper.GetBCD_A6(content.Skip(12 + i * datalen).Take(2).ToArray());
                //    lampdata.Voltage3 = CmdHelper.GetBCD_A6(content.Skip(14 + i * datalen).Take(2).ToArray());
                //    lampdata.Current3 = CmdHelper.GetBCD_A26(content.Skip(16 + i * datalen).Take(3).ToArray());
                //    lampdata.Power3 = CmdHelper.GetBCD_A10(content.Skip(19 + i * datalen).Take(3).ToArray());
                //    lampdata.Light3 = SubLight(content[22 + i * datalen], lampdata.Sn, lampdata.Updatetime);
                //}
            }

            var mode = content[23 + (count - 1) * datalen];
            var scence = content[24 + (count - 1) * datalen];
            var signal = content[25 + (count - 1) * datalen];

            DtuDAL.UpdateMulti(info.Sn, scence, mode, signal, dt);
        }

        private decimal SubLight(int light, string sn, DateTime date)
        {
            if (light > 100)
            {
                light = light - 100;
                if (light == 28)
                {
                    var alarm = new Alarm();
                    alarm.Sn = sn;
                    alarm.AlarmType = 0;
                    alarm.Content = "Ligth Broken";
                    alarm.UpdateTime = date;
                    AlarmDAL.Insert(alarm);
                }

                if (light == 29)
                {
                    var alarm = new Alarm();
                    alarm.Sn = sn;
                    alarm.AlarmType = 0;
                    alarm.Content = "Communication  Error";
                    alarm.UpdateTime = date;
                    AlarmDAL.Insert(alarm);
                }

                //if (light == 30)
                //{
                //    var alarm = new Alarm();
                //    alarm.Sn = sn;
                //    alarm.AlarmType = 0;
                //    alarm.Content = "控制器跟镇流器通讯错误";
                //    alarm.UpdateTime = date;
                //    AlarmDAL.Insert(alarm);
                //}
                if (light == 31)
                {
                    var alarm = new Alarm();
                    alarm.Sn = sn;
                    alarm.AlarmType = 0;
                    alarm.Content = "Control FAIL";
                    alarm.UpdateTime = date;
                    AlarmDAL.Insert(alarm);
                }
            }
            else
            {
                switch (light)
                {
                    case 0:
                        light = 0;
                        break;
                    case 1:
                        light = 50;
                        break;
                    case 2:
                        light = 65;
                        break;
                    case 3:
                        light = 80;
                        break;
                    case 4:
                        light = 100;
                        break;
                }
            }

            return light;
        }
    }
}